OpenClaw 会话管理与子代理协作
会话(Sessions)和子代理(Sub-agents)是 OpenClaw 实现复杂任务的核心机制。本文详解如何高效管理会话、spawn 子代理、协调多代理协作,构建强大的 AI 工作流。
概述
OpenClaw 的会话系统支持:
- 主会话 - 与用户的直接交互
- 子代理会话 - 为特定任务 spawn 的独立 AI 实例
- ACP 会话 - 与外部 AI 编码工具(如 Codex、Claude Code)集成
- 会话间通信 - 消息传递、状态共享
通过合理使用会话和子代理,你可以:
- 🔄 并行处理多个任务
- 🧠 为不同任务分配合适的模型
- 📦 隔离复杂任务的上下文
- ⏱️ 设置独立的超时和重试策略
- 💾 保持主会话简洁
一、会话系统架构
1.1 会话类型
┌─────────────────────────────────────────────────────┐
│ 会话类型 │
├─────────────────────────────────────────────────────┤
│ main │ 主会话,与用户直接交互 │
│ subagent │ 子代理会话,由主会话 spawn │
│ acp │ ACP 会话,与外部编码工具集成 │
│ isolated │ 隔离会话,独立上下文 │
└─────────────────────────────────────────────────────┘1.2 会话生命周期
创建 (spawn) → 运行 (running) → 完成 (completed)
↓
终止 (killed)1.3 核心 API
| API | 用途 | 说明 |
|---|---|---|
sessions_list | 列出会话 | 获取所有活跃会话 |
sessions_spawn | 创建会话 | spawn 子代理或 ACP 会话 |
sessions_send | 发送消息 | 向其他会话发送消息 |
sessions_history | 获取历史 | 查看会话消息历史 |
sessions_yield | 结束回合 | 等待子代理结果 |
subagents | 管理子代理 | list/kill/steer |
session_status | 查看状态 | 使用量、时间、成本 |
二、子代理基础
2.1 什么是子代理
子代理是由主会话 spawn 的独立 AI 实例,具有:
- 独立上下文 - 不共享主会话的历史消息
- 独立模型 - 可以为不同任务选择不同模型
- 独立超时 - 设置任务特定的超时时间
- 独立输出 - 完成后将结果返回给主会话
2.2 何时使用子代理
适合使用子代理的场景:
- ✅ 长时间运行的任务(>1 分钟)
- ✅ 需要不同模型专长的任务
- ✅ 可能失败需要重试的任务
- ✅ 需要隔离上下文的敏感任务
- ✅ 可以并行执行的多个任务
不适合使用子代理的场景:
- ❌ 简单快速的问题(直接处理)
- ❌ 需要连续对话的任务
- ❌ 依赖主会话实时上下文的场景
2.3 spawn 子代理
基本用法:
javascript
// 最简单的 spawn
const result = await sessions_spawn({
task: '分析这个 Python 文件的复杂度',
attachments: [{
name: 'main.py',
content: fileContent,
encoding: 'utf8'
}],
mode: 'run', // 'run' = 一次性运行,'session' = 持久会话
runtime: 'subagent' // 'subagent' 或 'acp'
})
console.log(result.output)完整参数:
javascript
await sessions_spawn({
// 必需
task: '任务描述',
// 运行模式
mode: 'run', // 'run' | 'session'
runtime: 'subagent', // 'subagent' | 'acp'
// 模型配置
model: 'claude-sonnet-4-5-20250929', // 可选,使用默认模型
thinking: 'medium', // 'low' | 'medium' | 'high'
// 超时配置
timeoutSeconds: 300, // 总超时
runTimeoutSeconds: 180, // 运行超时
// 工作目录
cwd: '/path/to/workdir',
// 附件
attachments: [{
name: 'filename.ext',
content: 'file content',
encoding: 'utf8', // 'utf8' | 'base64'
mimeType: 'text/plain'
}],
// 会话配置
label: 'code-analysis', // 会话标签
thread: false, // 是否线程绑定
cleanup: 'delete', // 'delete' | 'keep'
// 沙箱
sandbox: 'inherit', // 'inherit' | 'require'
// 输出流
streamTo: 'parent', // 流式输出到父会话
// ACP 专用
agentId: 'codex', // ACP agent ID
resumeSessionId: 'uuid' // 恢复现有 ACP 会话
})2.4 实战案例 1:代码分析器
javascript
async function analyzeCodebase(repoPath) {
console.log('🔍 开始代码库分析...')
// 1. 获取文件列表
const files = await exec({
command: `find ${repoPath} -name "*.py" -o -name "*.js" -o -name "*.ts" | head -50`
})
// 2. 为每个文件 spawn 分析子代理
const analysisPromises = files.stdout.split('\n')
.filter(f => f.trim())
.map(async (filePath) => {
const content = await read({ path: filePath })
return await sessions_spawn({
task: `分析以下代码文件:
- 代码质量评分(1-10)
- 潜在问题列表
- 优化建议
- 复杂度评估
返回 JSON 格式结果。`,
attachments: [{
name: path.basename(filePath),
content: content,
encoding: 'utf8'
}],
mode: 'run',
runtime: 'subagent',
timeoutSeconds: 120,
model: 'claude-sonnet-4-5-20250929' // 代码分析用较强模型
})
})
// 3. 并行执行所有分析
const results = await Promise.all(analysisPromises)
// 4. 汇总结果
const summary = {
totalFiles: results.length,
averageScore: results.reduce((sum, r) => sum + r.score, 0) / results.length,
issues: results.flatMap(r => r.issues),
recommendations: results.flatMap(r => r.recommendations)
}
return summary
}
// 使用
const analysis = await analyzeCodebase('/home/pao/projects/my-app')
console.log(`分析完成:${analysis.totalFiles} 个文件,平均分:${analysis.averageScore}`)2.5 实战案例 2:多语言翻译工作流
javascript
async function translateDocument(sourcePath, targetLanguages) {
// 1. 读取源文档
const sourceContent = await read({ path: sourcePath })
// 2. 为每种语言 spawn 翻译子代理
const translationPromises = targetLanguages.map(lang =>
sessions_spawn({
task: `将以下文档翻译成${lang}。
要求:
- 保持专业术语准确
- 保持原文格式(Markdown、代码块等)
- 本地化示例和文化引用
- 输出完整翻译,不要省略`,
attachments: [{
name: 'source.md',
content: sourceContent,
encoding: 'utf8'
}],
mode: 'run',
runtime: 'subagent',
timeoutSeconds: 300,
label: `translate-to-${lang}`
})
)
// 3. 等待所有翻译完成
const translations = await Promise.all(translationPromises)
// 4. 保存翻译结果
const results = {}
for (let i = 0; i < targetLanguages.length; i++) {
const lang = targetLanguages[i]
const outputPath = sourcePath.replace('.md', `.${lang}.md`)
await write({
path: outputPath,
content: translations[i].output
})
results[lang] = outputPath
}
return results
}
// 使用
const translated = await translateDocument(
'/docs/guide.md',
['英文', '日文', '法文', '西班牙文']
)
console.log('翻译完成:', translated)三、会话管理
3.1 列出会话
javascript
// 列出所有会话
async function listAllSessions() {
return await sessions_list({
limit: 50, // 最多返回数量
activeMinutes: 60, // 最近 60 分钟活跃
kinds: ['subagent'] // 过滤类型:'main' | 'subagent' | 'acp'
})
}
// 查找特定标签的会话
async function findSessionByLabel(label) {
const sessions = await sessions_list({ limit: 100 })
return sessions.find(s => s.label === label)
}
// 获取会话状态
async function getSessionStatus(sessionKey) {
return await session_status({ sessionKey })
}3.2 会话历史
javascript
// 获取会话历史
async function getSessionHistory(sessionKey, limit = 50) {
return await sessions_history({
sessionKey,
limit,
includeTools: true // 包含工具调用记录
})
}
// 分析会话历史
async function analyzeSession(sessionKey) {
const history = await getSessionHistory(sessionKey)
const stats = {
totalMessages: history.messages.length,
toolCalls: history.messages.filter(m => m.tool).length,
tokensUsed: history.usage?.total_tokens || 0,
duration: history.messages[history.messages.length - 1].timestamp -
history.messages[0].timestamp
}
return stats
}3.3 会话间通信
javascript
// 向其他会话发送消息
async function sendToSession(sessionKey, message) {
return await sessions_send({
sessionKey,
message,
timeoutSeconds: 60 // 等待响应超时
})
}
// 向标签匹配的会话发送
async function sendToLabel(label, message) {
const session = await findSessionByLabel(label)
if (!session) {
throw new Error(`未找到标签为 ${label} 的会话`)
}
return await sessions_send({
label, // 直接使用标签
message
})
}
// 广播消息到多个会话
async function broadcastToSessions(sessionKeys, message) {
return await Promise.all(
sessionKeys.map(key => sendToSession(key, message))
)
}3.4 实战案例 3:分布式数据处理
javascript
async function processLargeDataset(inputFile, chunkSize = 1000) {
// 1. 读取并分块
const data = await readLargeFile(inputFile)
const chunks = chunkArray(data, chunkSize)
console.log(`数据分块:${chunks.length} 块,每块 ${chunkSize} 条`)
// 2. 为每个块 spawn 处理子代理
const chunkPromises = chunks.map(async (chunk, index) => {
return await sessions_spawn({
task: `处理以下数据块(第${index + 1}/${chunks.length}块):
- 数据清洗
- 格式标准化
- 异常值检测
- 生成统计摘要
返回处理后的数据和统计信息。`,
attachments: [{
name: `chunk-${index}.json`,
content: JSON.stringify(chunk),
encoding: 'utf8'
}],
mode: 'run',
runtime: 'subagent',
timeoutSeconds: 180,
label: `data-processor-${index}`,
cleanup: 'delete' // 完成后清理
})
})
// 3. 并行处理(限制并发数)
const CONCURRENCY = 5
const results = []
for (let i = 0; i < chunkPromises.length; i += CONCURRENCY) {
const batch = chunkPromises.slice(i, i + CONCURRENCY)
const batchResults = await Promise.all(batch)
results.push(...batchResults)
console.log(`进度:${Math.min(i + CONCURRENCY, chunks.length)}/${chunks.length}`)
}
// 4. 合并结果
const mergedData = results.flatMap(r => r.processedData)
const aggregatedStats = aggregateStats(results.map(r => r.stats))
// 5. 保存结果
await write({
path: inputFile.replace('.json', '.processed.json'),
content: JSON.stringify(mergedData, null, 2)
})
await write({
path: inputFile.replace('.json', '.stats.json'),
content: JSON.stringify(aggregatedStats, null, 2)
})
return {
totalRecords: mergedData.length,
stats: aggregatedStats
}
}四、子代理管理
4.1 列出子代理
javascript
// 列出所有子代理
async function listSubagents() {
return await subagents({
action: 'list',
recentMinutes: 60 // 最近 60 分钟
})
}
// 获取子代理详情
async function getSubagentDetails(target) {
const list = await listSubagents()
return list.find(a => a.id === target || a.label === target)
}4.2 终止子代理
javascript
// 终止指定子代理
async function killSubagent(target) {
return await subagents({
action: 'kill',
target
})
}
// 批量终止
async function killSubagentsByLabel(labelPattern) {
const agents = await listSubagents()
const toKill = agents.filter(a => a.label?.includes(labelPattern))
for (const agent of toKill) {
await killSubagent(agent.id)
console.log(`已终止:${agent.label}`)
}
return toKill.length
}
// 终止超时子代理
async function cleanupTimeoutAgents(maxAgeMinutes = 60) {
const agents = await listSubagents()
const now = Date.now()
let cleaned = 0
for (const agent of agents) {
const age = (now - agent.createdAt) / 1000 / 60
if (age > maxAgeMinutes && agent.status === 'running') {
await killSubagent(agent.id)
cleaned++
}
}
return cleaned
}4.3 调整子代理
javascript
// 向运行中的子代理发送指导
async function steerSubagent(target, message) {
return await subagents({
action: 'steer',
target,
message
})
}
// 示例:调整分析方向
async function redirectAnalysis(agentId, newFocus) {
await steerSubagent(agentId, `
请调整分析方向,重点关注:${newFocus}
之前分析的内容仍然有效,请在此基础上深入。
`)
}4.4 实战案例 4:子代理健康检查
javascript
class SubagentManager {
constructor() {
this.maxConcurrent = 10
this.maxAgeMinutes = 120
}
// 健康检查
async healthCheck() {
const agents = await listSubagents()
const report = {
total: agents.length,
running: agents.filter(a => a.status === 'running').length,
completed: agents.filter(a => a.status === 'completed').length,
failed: agents.filter(a => a.status === 'failed').length,
old: 0,
orphaned: 0
}
// 检查老旧子代理
const now = Date.now()
for (const agent of agents) {
const age = (now - agent.createdAt) / 1000 / 60
if (age > this.maxAgeMinutes) {
report.old++
if (agent.status === 'running') {
console.warn(`⚠️ 子代理运行超时:${agent.label || agent.id}`)
}
}
// 检查孤立子代理(父会话已结束)
if (!agent.parentSession) {
report.orphaned++
}
}
return report
}
// 自动清理
async autoCleanup() {
const cleaned = await cleanupTimeoutAgents(this.maxAgeMinutes)
console.log(`清理了 ${cleaned} 个超时的子代理`)
// 清理已完成的子代理记录
const agents = await listSubagents()
for (const agent of agents) {
if (agent.status === 'completed' || agent.status === 'failed') {
// 已完成/失败的子代理可以清理
// 注意:实际清理可能需要额外 API
}
}
}
// 并发控制
async spawnWithLimit(task, options) {
// 检查当前运行数
const agents = await listSubagents()
const running = agents.filter(a => a.status === 'running').length
if (running >= this.maxConcurrent) {
console.log('等待子代理完成...')
await sleep(5000)
return this.spawnWithLimit(task, options)
}
return await sessions_spawn({ task, ...options })
}
}
// 使用
const manager = new SubagentManager()
// 定期健康检查
setInterval(async () => {
const report = await manager.healthCheck()
console.log('子代理状态:', report)
if (report.old > 0 || report.orphaned > 0) {
await manager.autoCleanup()
}
}, 5 * 60 * 1000) // 每 5 分钟五、ACP 会话集成
5.1 什么是 ACP
ACP(AI Coding Protocol)是 OpenClaw 与外部 AI 编码工具(如 Codex、Claude Code、Gemini CLI)集成的协议。
支持的 ACP Agent:
codex- OpenAI Codex CLIclaude-code- Anthropic Claude Codegemini- Google Gemini CLI
5.2 spawn ACP 会话
javascript
// 基本用法
async function runCodexTask(task) {
return await sessions_spawn({
task,
runtime: 'acp',
agentId: 'codex', // 必需,除非配置了 acp.defaultAgent
mode: 'run', // 一次性运行
timeoutSeconds: 600 // 10 分钟超时
})
}
// 持久 ACP 会话(用于多轮对话)
async function createPersistentCodexSession(label) {
return await sessions_spawn({
task: '初始化编码会话',
runtime: 'acp',
agentId: 'codex',
mode: 'session', // 持久会话
thread: true, // 线程绑定
label
})
}
// 恢复现有 ACP 会话
async function resumeCodexSession(sessionId, newTask) {
return await sessions_spawn({
task: newTask,
runtime: 'acp',
agentId: 'codex',
resumeSessionId: sessionId,
mode: 'session'
})
}5.3 实战案例 5:自动化代码修复
javascript
async function autoFixCode(repoPath, issueDescription) {
console.log('🔧 开始自动代码修复...')
// 1. 获取 Git 状态
const gitStatus = await exec({
command: `cd ${repoPath} && git status --porcelain`
})
// 2. spawn ACP 会话进行修复
const result = await sessions_spawn({
task: `修复以下代码问题:${issueDescription}
Git 状态:
${gitStatus.stdout}
要求:
1. 分析问题根源
2. 修改相关代码文件
3. 运行测试验证修复
4. 提交更改(如果测试通过)
工作目录:${repoPath}`,
runtime: 'acp',
agentId: 'codex',
mode: 'session',
thread: true,
label: 'auto-fix',
timeoutSeconds: 900, // 15 分钟
cwd: repoPath
})
// 3. 验证修复
const testResult = await exec({
command: `cd ${repoPath} && npm test`,
timeout: 120
})
if (testResult.exitCode === 0) {
console.log('✅ 修复成功,测试通过')
// 提交更改
await exec({
command: `cd ${repoPath} && git add -A && git commit -m "fix: ${issueDescription}"`
})
} else {
console.log('❌ 测试失败,需要人工审查')
// 通知用户
await sessions_send({
sessionKey: 'main',
message: `⚠️ 自动修复完成但测试失败:
问题:${issueDescription}
测试输出:${testResult.stderr}
请人工审查更改。`
})
}
return {
success: testResult.exitCode === 0,
output: result.output,
testResult
}
}5.4 ACP 与 Subagent 对比
| 特性 | Subagent | ACP |
|---|---|---|
| 用途 | 通用 AI 任务 | 编码专用 |
| 工具 | OpenClaw 工具集 | 外部 CLI 工具 |
| 工作目录 | 继承或指定 | 通常指定项目目录 |
| 持久化 | 支持 session 模式 | 支持 session 模式 |
| 适用场景 | 分析、写作、数据处理 | 代码修改、调试、重构 |
六、高级模式
6.1 工作流编排
javascript
class WorkflowOrchestrator {
constructor() {
this.steps = []
this.context = {}
}
// 添加步骤
addStep(name, fn) {
this.steps.push({ name, fn })
return this
}
// 执行工作流
async execute() {
const results = {}
for (const step of this.steps) {
console.log(`执行步骤:${step.name}`)
try {
const result = await step.fn(this.context)
results[step.name] = result
// 更新上下文
Object.assign(this.context, result.context || {})
} catch (error) {
console.error(`步骤失败:${step.name}`, error)
// 错误处理策略
if (step.onFailure === 'continue') {
results[step.name] = { error: error.message }
} else {
throw error // 默认:失败即终止
}
}
}
return { results, context: this.context }
}
}
// 使用示例:内容发布工作流
const workflow = new WorkflowOrchestrator()
.addStep('分析需求', async (ctx) => {
const analysis = await sessions_spawn({
task: `分析内容需求:${ctx.requirement}`,
mode: 'run'
})
return { analysis: analysis.output }
})
.addStep('创建大纲', async (ctx) => {
const outline = await sessions_spawn({
task: `基于分析创建大纲:${ctx.analysis}`,
mode: 'run'
})
return { outline: outline.output }
})
.addStep('撰写内容', async (ctx) => {
const content = await sessions_spawn({
task: `根据大纲撰写内容:${ctx.outline}`,
mode: 'run',
timeoutSeconds: 600
})
return { content: content.output }
})
.addStep('审核质量', async (ctx) => {
const review = await sessions_spawn({
task: `审核内容质量:${ctx.content}`,
mode: 'run'
})
return { review: review.output }
})
.addStep('发布', async (ctx) => {
// 发布逻辑
await publishContent(ctx.content)
return { published: true }
})
// 执行
const result = await workflow.execute()6.2 并行聚合模式
javascript
async function parallelAggregate(tasks, aggregator) {
// 1. spawn 所有子代理
const promises = tasks.map(task =>
sessions_spawn({
task: task.description,
mode: 'run',
label: task.label
})
)
// 2. 等待全部完成
const results = await Promise.allSettled(promises)
// 3. 分离成功和失败
const successes = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value)
const failures = results
.filter(r => r.status === 'rejected')
.map(r => r.reason)
// 4. 聚合结果
const aggregated = await aggregator(successes)
return {
aggregated,
successes: successes.length,
failures: failures.length,
failureDetails: failures
}
}
// 使用:多源信息聚合
const report = await parallelAggregate(
[
{ description: '搜索最新 AI 新闻', label: 'news' },
{ description: '获取技术趋势报告', label: 'trends' },
{ description: '分析社区讨论热点', label: 'community' },
{ description: '整理 GitHub 热门项目', label: 'github' }
],
async (results) => {
// 使用另一个子代理聚合
const aggregator = await sessions_spawn({
task: `聚合以下信息生成综合报告:
${results.map((r, i) => `## 来源${i+1}\n${r.output}`).join('\n')}`,
mode: 'run'
})
return aggregator.output
}
)6.3 链式处理模式
javascript
async function chainProcess(input, processors) {
let current = input
for (const processor of processors) {
console.log(`处理阶段:${processor.name}`)
const result = await sessions_spawn({
task: processor.task(current),
mode: 'run',
timeoutSeconds: processor.timeout || 120
})
current = result.output
// 可选:质量检查
if (processor.validate) {
const valid = await processor.validate(current)
if (!valid) {
throw new Error(`阶段 ${processor.name} 输出未通过验证`)
}
}
}
return current
}
// 使用:文章润色链
const polished = await chainProcess(
draftArticle,
[
{
name: '语法检查',
task: (text) => `检查并修正以下文本的语法错误:${text}`,
timeout: 60
},
{
name: '风格优化',
task: (text) => `优化以下文本的写作风格,使其更专业:${text}`,
timeout: 90
},
{
name: '结构重组',
task: (text) => `重组以下文本结构,提升可读性:${text}`,
timeout: 90
},
{
name: '最终审校',
task: (text) => `审校以下文本,确保一致性和准确性:${text}`,
timeout: 60,
validate: async (text) => {
// 验证逻辑
return text.length > 1000
}
}
]
)6.4 实战案例 6:智能研究助手
javascript
class ResearchAssistant {
constructor(topic) {
this.topic = topic
this.findings = []
}
async research() {
console.log(`📚 开始研究:${this.topic}`)
// 阶段 1:背景调研
const background = await sessions_spawn({
task: `调研主题"${this.topic}"的背景信息:
- 核心概念定义
- 发展历史
- 关键人物/组织
- 当前状态`,
mode: 'run',
label: 'background-research'
})
this.findings.push({ type: 'background', content: background.output })
// 阶段 2:并行深度研究
const deepResearch = await Promise.all([
sessions_spawn({
task: `分析${this.topic}的技术细节和实现方案`,
mode: 'run',
label: 'technical-analysis'
}),
sessions_spawn({
task: `调研${this.topic}的商业应用和案例`,
mode: 'run',
label: 'business-analysis'
}),
sessions_spawn({
task: `分析${this.topic}的挑战和未来趋势`,
mode: 'run',
label: 'trend-analysis'
})
])
this.findings.push(
{ type: 'technical', content: deepResearch[0].output },
{ type: 'business', content: deepResearch[1].output },
{ type: 'trends', content: deepResearch[2].output }
)
// 阶段 3:综合报告
const report = await sessions_spawn({
task: `基于以下研究发现,撰写综合研究报告:
${this.findings.map(f => `## ${f.type}\n${f.content}`).join('\n\n')}`,
mode: 'run',
timeoutSeconds: 600,
label: 'report-writing'
})
return {
topic: this.topic,
findings: this.findings,
report: report.output,
timestamp: new Date().toISOString()
}
}
}
// 使用
const assistant = new ResearchAssistant('AI Agent 自主性')
const result = await assistant.research()
// 保存报告
await write({
path: `research/${result.topic.replace(/\s+/g, '-')}.md`,
content: result.report
})七、最佳实践
7.1 性能优化
并发控制
javascript
// 限制并发子代理数量
const MAX_CONCURRENT = 5
const semaphore = { count: 0, queue: [] }
async function spawnWithSemaphore(task, options) {
if (semaphore.count >= MAX_CONCURRENT) {
await new Promise(resolve => semaphore.queue.push(resolve))
}
semaphore.count++
try {
return await sessions_spawn({ task, ...options })
} finally {
semaphore.count--
if (semaphore.queue.length > 0) {
semaphore.queue.shift()()
}
}
}超时设置
javascript
// 根据任务类型设置合理超时
const TIMEOUTS = {
analysis: 120, // 分析任务 2 分钟
writing: 300, // 写作任务 5 分钟
coding: 600, // 编码任务 10 分钟
research: 900 // 研究任务 15 分钟
}
await sessions_spawn({
task,
timeoutSeconds: TIMEOUTS[taskType]
})7.2 错误处理
javascript
async function spawnWithRetry(task, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await sessions_spawn({ task, ...options })
} catch (error) {
if (i === maxRetries - 1) throw error
console.log(`重试 ${i+1}/${maxRetries}: ${error.message}`)
await sleep(2000 * (i + 1)) // 指数退避
}
}
}7.3 资源管理
javascript
// 定期清理
async function cleanupResources() {
// 清理超时子代理
await cleanupTimeoutAgents(120)
// 清理已完成会话
const sessions = await sessions_list({ limit: 100 })
for (const session of sessions) {
if (session.status === 'completed' && session.age > 24 * 60) {
// 清理超过 24 小时的已完成会话
}
}
}
// 监控资源使用
async function monitorUsage() {
const status = await session_status({})
if (status.usage.total_tokens > 100000) {
console.warn('⚠️ Token 使用量过高')
}
if (status.cost > 10) {
console.warn('⚠️ 成本超过阈值')
}
}7.4 调试技巧
javascript
// 详细日志
async function spawnWithLogging(task, options) {
const startTime = Date.now()
console.log(`[SPAWN] ${options.label || 'unnamed'}: ${task.slice(0, 50)}...`)
try {
const result = await sessions_spawn({ task, ...options })
const duration = Date.now() - startTime
console.log(`[COMPLETE] ${options.label}: ${duration}ms`)
return result
} catch (error) {
console.error(`[ERROR] ${options.label}: ${error.message}`)
throw error
}
}
// 保存会话快照
async function saveSessionSnapshot(sessionKey) {
const history = await sessions_history({ sessionKey, includeTools: true })
await write({
path: `logs/session-${sessionKey}-${Date.now()}.json`,
content: JSON.stringify(history, null, 2)
})
}八、总结
核心要点
- 子代理是处理复杂任务的核心工具
- 合理设置超时和重试策略
- 使用标签组织和管理会话
- 定期清理避免资源泄漏
- ACP 会话专为编码任务优化
选择指南
| 场景 | 推荐方案 |
|---|---|
| 简单问题 | 直接处理 |
| 长时间任务 | spawn 子代理 |
| 编码任务 | ACP 会话 |
| 并行处理 | 多个子代理 |
| 多轮对话 | session 模式 |
| 敏感任务 | 隔离会话 |
进阶方向
- 📖 研究 OpenClaw 会话源码
- 🔧 开发自定义会话管理工具
- 🏗️ 构建复杂工作流编排系统
- 📊 实现会话分析和优化
🟢🐉 开始构建你的多代理协作系统吧!